home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).adf / Sol / sol.c < prev    next >
C/C++ Source or Header  |  1989-01-18  |  15KB  |  797 lines

  1. /*    sol.c - solitare 
  2.       ported to the amiga from unix 4.3bsd
  3.       by Joel Swank 9/22/87
  4. */
  5. #include    <stdio.h>
  6. #include    <time.h>
  7. #include    <exec/types.h>
  8. #include    <stat.h>
  9. #include    <functions.h>
  10.  
  11. #undef        TRUE
  12. #undef        FALSE
  13. #define        TRUE 1
  14. #define        FALSE 0
  15.  
  16. int    amode;
  17. int    cnt;
  18. int    cheat;
  19. int    deck[53];
  20. int    over[53];
  21. int    ace[4][14];
  22. int    run[7][14];
  23. int    hidden[7][8];
  24. char    cmd[40], *cp;
  25. char    *resgb;
  26.  
  27.  
  28.  
  29. extern    struct tm    *localtime();
  30. extern    char        *getenv();
  31. extern    long        time();
  32.  
  33. main(n, a)
  34. char **a;
  35.  {
  36.     int i, p, c, r, s;
  37.     long now;
  38.     struct tm *tp;
  39.     int from;
  40.     int dest;
  41.     int brkflg;
  42.  
  43.     amode = 0;
  44.     (void) time(&now);
  45.     tp = localtime(&now);
  46.     srand((unsigned) (tp->tm_sec));
  47.     init();
  48.     set_raw();
  49.     for (i = 0; i < 52; i++)
  50.       deck[i] = i;
  51.     deck[52] = -1;
  52.     shuffle(deck);
  53.     for (i = 0; i < 4; i++)
  54.       ace[i][0] = -1;
  55.     for (i = 0; i < 7; i++)
  56.       hidden[i][0] = run[i][0] = -1;
  57.     over[0] = -1;
  58.     for (p = 0; p < 7; p++)
  59.       for (c = p; c < 7; c++)
  60.     put(hidden[c],get(deck));
  61.     for (r = 0; r < 7; r++)
  62.       put(run[r],get(hidden[r]));
  63.     redraw(TRUE);
  64.     for (r = 0; r < 7; r++)
  65.      {
  66.     while (getvalue(run[r][0]) == 0)
  67.      {
  68.         s = getsuit(run[r][0]);
  69.         put(ace[s],get(run[r]));
  70.         put(run[r],get(hidden[r]));
  71.         redraw(FALSE);
  72.      }
  73.      }
  74.     cnt = cheat = 0;
  75.     if (n > 1 && !strcmp(a[1], "auto"))
  76.       autopilot();
  77.     brkflg = 1;
  78.     while (brkflg)
  79.      {
  80.     cnt++;
  81.     do
  82.      {
  83.         moveto(17, 0);
  84.         (void) printf("cmd:%d> ", cnt);
  85.         cleol();
  86.         (void) fflush(stdout);
  87.      } while (!getst(cp = cmd));
  88.     while (*cp == ' ' || *cp == '\t')
  89.       cp++;
  90.     switch (*cp++)
  91.      {
  92.         case 'a':
  93.           autopilot();
  94.         break;
  95.         case 'm':
  96.          {
  97.         while (*cp == ' ' || *cp == '\t')
  98.           cp++;
  99.         if (!(from = *cp++) || ((from < '1' || from > '7') &&
  100.                                 from != 'd'))
  101.          {
  102.             whoops();
  103.             continue;
  104.          }
  105.         while (*cp == ' ' || *cp == '\t')
  106.           cp++;
  107.         if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
  108.                 dest != 'a') || !movecard(from, dest, FALSE))
  109.          {
  110.             whoops();
  111.             continue;
  112.          }
  113.         if (cardsleft() == 0)
  114.           finish();
  115.          }
  116.         break;
  117.         case 't':
  118.         case 0:
  119.           thumb();
  120.         break;
  121.         case 'h':
  122.         case '?':
  123.           disphelp();
  124.         break;
  125.         case 'r':
  126.           disprules();
  127.         break;
  128.         case 'q':
  129.           brkflg = 0;
  130.         break;
  131.         case 's':
  132.          {
  133.         while (peek(over) != -1)
  134.           put(deck, get(over));
  135.         shuffle(deck);
  136.         redraw(FALSE);
  137.         cheat++;
  138.          }
  139.         break;
  140.         case 'p':
  141.          {
  142.         while (*cp == ' ' || *cp == '\t')
  143.           cp++;
  144.         if (!(from = *cp++) || from < '1' || from > '7')
  145.          {
  146.             whoops();
  147.             continue;
  148.          }
  149.             if (hidden[from -= '1'][0] != -1)
  150.          {
  151.             while (hidden[from][0] != -1)
  152.               put(deck, get(hidden[from]));
  153.             redraw(FALSE);
  154.             cheat++;
  155.          }
  156.         else
  157.           whoops();
  158.          }
  159.         break;
  160.         case 'd':
  161.          {
  162.         moveto(19, 0);
  163.         (void) printf("%d cards in deck:\n", lstlen(deck) + lstlen(over));
  164.         i = lstlen(deck);
  165.         while (--i != -1)
  166.          {
  167.             pcard(deck[i]);
  168.             (void) putchar(' ');
  169.          }
  170.         (void) putchar('\n');
  171.         for (i = 0; over[i] != -1; i++)
  172.          {
  173.             pcard(over[i]);
  174.             (void) putchar(' ');
  175.          }
  176.         (void) printf("\nHit return -");
  177.         (void) fflush(stdout);
  178.         (void) getchar();
  179.         moveto(19, 0);
  180.         for (i = 0; i < 4; i++)
  181.          {
  182.             cleol();
  183.             (void) putchar('\n');
  184.          }
  185.         cheat++;
  186.          }
  187.         break;
  188.         case 'w':
  189.          {
  190.         while (*cp == ' ' || *cp == '\t')
  191.           cp++;
  192.         if (!(from = *cp++) || from < '1' || from > '7')
  193.          {
  194.             whoops();
  195.             continue;
  196.          }
  197.         moveto(19, 0);
  198.         from -= '1';
  199.         (void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
  200.                                 from + '1');
  201.         for (i = 0; hidden[from][i] != -1; i++)
  202.          {
  203.             pcard(hidden[from][i]);
  204.             (void) putchar(' ');
  205.          }
  206.         (void) printf("\nHit return -");
  207.         (void) fflush(stdout);
  208.         (void) getchar();
  209.         moveto(19,0);
  210.         for (i = 0; i < 4; i++)
  211.          {
  212.             cleol();
  213.             (void) putchar('\n');
  214.          }
  215.         cheat++;
  216.          }
  217.         break;
  218.         default:
  219.           whoops();
  220.         break;
  221.      }
  222.      }
  223.     moveto(19, 0);
  224.     cleol();
  225.     (void) printf("I see you gave up\n");
  226.     if (cheat > 0)
  227.       (void) printf("    ... even after you cheated %d times!\n", cheat);
  228.     else
  229.       (void) printf("    ... but at least you didn't cheat...congratulations!\n");
  230.     unwind();
  231.  }
  232.  
  233. unwind()
  234.  {
  235.     moveto(23, 0);
  236.     deinit();
  237.     set_con();
  238.     exit(0);
  239.  }
  240.  
  241. movecard(from,dest,limitmove)
  242.  {
  243.     if (from == dest)
  244.       return(FALSE);
  245.     if (from == 'd')
  246.       return(dest == 'a' ? deck2ace() : deck2run(dest));
  247.     else
  248.       return(dest == 'a' ? run2ace(from) : run2run(from,dest,limitmove));
  249.  }
  250.  
  251. deck2run(dest)
  252.  {
  253.     int fcard, dcard, s, ok;
  254.  
  255.     if ((fcard = peek(over)) == -1)
  256.       return(FALSE);
  257.     dcard = peek(run[dest -= '1']);
  258.     if (ok = chk2run(fcard,dcard))
  259.      {
  260.     put(run[dest],get(over));
  261.     redraw(FALSE);
  262.     while (getvalue(peek(over)) == 0)
  263.      {
  264.         s = getsuit(peek(over));
  265.         put(ace[s],get(over));
  266.         redraw(FALSE);
  267.      }
  268.      }
  269.     return(ok);
  270.  }
  271.  
  272. deck2ace()
  273.  {
  274.     int fcard, s, ok;
  275.  
  276.     if (ok = (fcard = peek(over)) != -1 &&
  277.         getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  278.      {
  279.     put(ace[s], get(over));
  280.     redraw(FALSE);
  281.     while (getvalue(peek(over)) == 0)
  282.      {
  283.         s = getsuit(peek(over));
  284.         put(ace[s],get(over));
  285.         redraw(FALSE);
  286.      }
  287.      }
  288.     return(ok);
  289.  }
  290.  
  291. run2ace(from)
  292.  {
  293.     int fcard, s, ok;
  294.  
  295.     fcard = peek(run[from -= '1']);
  296.     if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  297.      {
  298.     put(ace[s], get(run[from]));
  299.     redraw(FALSE);
  300.     if (run[from][0] == -1 && hidden[from][0] >= 0)
  301.      {
  302.         while (getvalue(peek(hidden[from])) == 0)
  303.          {
  304.         s = getsuit(peek(hidden[from]));
  305.         put(ace[s],get(hidden[from]));
  306.         redraw(FALSE);
  307.          }
  308.         put(run[from],get(hidden[from]));
  309.         redraw(FALSE);
  310.      }
  311.      }
  312.     return(ok);
  313.  }
  314.  
  315. run2run(from,dest,limitmove)
  316.  {
  317.     int fcard, dcard, i, ok, s;
  318.  
  319.     if ((fcard = run[from -= '1'][0]) == -1)
  320.       return(FALSE);
  321.     dcard = peek(run[dest -= '1']);
  322.     if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
  323.                         lstlen(hidden[from]) == 0)
  324.       return(FALSE);
  325.     if (amode > 0 && !limitmove && lstlen(hidden[from]) == 0)
  326.       return(FALSE);
  327.     if (ok = chk2run(fcard,dcard))
  328.      {
  329.     for (i = 0; run[from][i] != -1; i++)
  330.       put(run[dest], run[from][i]);
  331.     run[from][0] = -1;
  332.     redraw(FALSE);
  333.     if (lstlen(hidden[from]) > 0)
  334.      {
  335.         while (getvalue(peek(hidden[from])) == 0)
  336.          {
  337.         s = getsuit(peek(hidden[from]));
  338.         put(ace[s],get(hidden[from]));
  339.         redraw(FALSE);
  340.          }
  341.         put(run[from],get(hidden[from]));
  342.         redraw(FALSE);
  343.      }
  344.      }
  345.     return(ok);
  346.  }
  347.  
  348. chk2run(fcard,dcard)
  349.  {
  350.     if (dcard == -1 && getvalue(fcard) == 12)
  351.       return(TRUE);
  352.     return(getvalue(dcard) - 1 == getvalue(fcard) &&
  353.                 getcolour(dcard) != getcolour(fcard));
  354.  }
  355.  
  356. finish()
  357.  {
  358.     int i, k;
  359.  
  360.     moveto(19,0);
  361.     (void) printf("\007I'll finish for you now\007");
  362.     (void) fflush(stdout);
  363.     do
  364.      {
  365.     k = FALSE;
  366.     for (i = 0; i < 7; i++)
  367.       k = movecard(i + '1', 'a', FALSE) || k;
  368.      } while (k);
  369.     moveto(20,0);
  370.     cleol();
  371.     (void) printf("\007You WIN\007\n");
  372.     if (cheat > 0)
  373.       (void) printf("    ... but you cheated %d times!", cheat);
  374.     else
  375.       (void) printf("    ... and without cheating ... congratulations!");
  376.     unwind();
  377.  }
  378.  
  379. autopilot()
  380.  {
  381.     int i, j, k;
  382.     int iter;
  383.  
  384.     moveto(19,0);
  385.     (void) printf("Going into automatic mode...");
  386.     (void) fflush(stdout);
  387.     amode = TRUE;
  388.     while (cardsleft() > 0)
  389.      {
  390.     k = FALSE;
  391.          iter = 0;
  392.     for (i = 0; i < 7; i++)
  393.       for (j = 0; j < 7; j++)
  394.         k = movecard(i + '1', j + '1', TRUE) || k;
  395.     for (i = 0; i < 7; i++)
  396.      {
  397.         k = movecard(i + '1', 'a', FALSE) || k;
  398.         k = movecard('d', i + '1', FALSE) || k;
  399.      }
  400.     k = movecard('d', 'a', FALSE) || k;
  401.     if (!k)
  402.      {
  403.         if (iter--)
  404.           thumb();
  405.         else
  406.           break;
  407.      }
  408.     else
  409.       iter = lstlen(over) + lstlen(deck);
  410.      }
  411.     do
  412.      {
  413.     k = FALSE;
  414.     for (i = 0; i < 7; i++)
  415.       k = movecard(i + '1', 'a', FALSE) || k;
  416.      } while (k);
  417.     moveto(19, 28);
  418.     if (cardsleft() == 0)
  419.      {
  420.     (void) printf("\007YEA...\007");
  421.     (void) fflush(stdout);
  422.     for (i = 0; i < 7; i++)
  423.       if (movecard(i + '1', 'a', FALSE));
  424.     moveto(19, 34);
  425.     (void) printf("I won!!!!!");
  426.      }
  427.     else
  428.      {
  429.     (void) printf("I couldn't win this time");
  430.     moveto(20, 0);
  431.     (void) printf("%d cards in deck", lstlen(deck) + lstlen(over));
  432.      }
  433.     unwind();
  434.  }
  435.  
  436. redraw(display)
  437. int display;
  438.  {
  439.     static long_run[7];
  440.     static long_hide[7];
  441.     static long_ace[4];
  442.     static base_run[7];
  443.  
  444.     int i, j;
  445.  
  446.     if (display)
  447.      {
  448.     clear();
  449.     for (i = 0; i < 7; i++)
  450.      {
  451.         long_run[i] = long_hide[i] = base_run[i] = -1;
  452.         moveto(0, 8 + i * 5);
  453.         (void) putchar(i + '1');
  454.      }
  455.     for (i = 0; i < 4; i++)
  456.       long_ace[i] = -1;
  457.     moveto(0,56);
  458.     (void) printf("ACES");
  459.     moveto(6,56);
  460.     (void) printf("DECK");
  461.      }
  462.     for (i = 0; i < 7; i++)
  463.      {
  464.     if (long_hide[i] != lstlen(hidden[i]))
  465.      {
  466.         moveto(2, 8 + i * 5);
  467.         (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
  468.         long_hide[i] = lstlen(hidden[i]);
  469.      }
  470.      }
  471.     for (i = 0; i < 4; i++)
  472.      {
  473.     if (long_ace[i] != lstlen(ace[i]))
  474.      {
  475.         moveto(2, 49 + i * 5);
  476.         if (ace[i][0] != -1)
  477.           pcard(peek(ace[i]));
  478.         else
  479.           (void) printf("--");
  480.         long_ace[i] = lstlen(ace[i]);
  481.      }
  482.      }
  483.     moveto(8, 55);
  484.     (void) printf(lstlen(deck) ? "##  " : "    ");
  485.     if (lstlen(over))
  486.       pcard(peek(over));
  487.     else
  488.       (void) printf("  ");
  489.     for (i = 0; i < 7; i++)
  490.      {
  491.     if (long_run[i] != lstlen(run[i]) ||
  492.                 (long_run[i] == 1 && base_run[i] != run[i][0]))
  493.      {
  494.         for (j = 0; run[i][j] != -1; j++)
  495.          {
  496.         moveto(j + 4, 7 + i * 5);
  497.         if (run[i][j] == -1)
  498.           (void) printf("  ");
  499.         else
  500.           pcard(run[i][j]);
  501.          }
  502.         while (j < long_run[i])
  503.          {
  504.         moveto(j++ + 4, 7 + i * 5);
  505.         (void) printf("  ");
  506.          }
  507.         long_run[i] = lstlen(run[i]);
  508.         base_run[i] = run[i][0];
  509.      }
  510.      }
  511.     (void) fflush(stdout);
  512.     (void) Delay(10L);
  513.  }
  514.  
  515. thumb()
  516.  {
  517.     int i, s;
  518.  
  519.     if (deck[0] == -1)
  520.      {
  521.     if (over[0] == -1)
  522.       return;
  523.     while (over[0] != -1)
  524.       put(deck, get(over));
  525.      }
  526.     for (i = 0; i < 3; i++)
  527.       if (deck[0] != -1)
  528.     put(over,get(deck));
  529.     redraw(FALSE);
  530.     while (getvalue(peek(over)) == 0)
  531.      {
  532.     s = getsuit(peek(over));
  533.     put(ace[s], get(over));
  534.     redraw(FALSE);
  535.      }
  536.     if (over[0] == -1 && deck[0] != -1)
  537.       thumb();
  538.  }
  539.  
  540. pcard(card)
  541.  {
  542.     int i;
  543.  
  544.     if ((i = getcolour(card)) != 0)
  545.       standout();
  546.     (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
  547.     if (i)
  548.       standend();
  549.  }
  550.  
  551.  
  552. getvalue(card)
  553.  {
  554.     return(card % 13);
  555.  }
  556.  
  557. getsuit(card)
  558.  {
  559.     return(card / 13);
  560.  }
  561.  
  562. getcolour(card)
  563.  {
  564.     return(card / 26);
  565.  }
  566.  
  567. cardsleft()
  568.  {
  569.     int i, t;
  570.  
  571.     t = lstlen(deck) + lstlen(over);
  572.     for (i = 0; i < 7; i++)
  573.       t += lstlen(hidden[i]);
  574.     return(t);
  575.  }
  576.  
  577. whoops()
  578.  {
  579.     moveto(17,0);
  580.     (void) printf("\007Invalid Command: '%s'\007", cmd);
  581.     (void) fflush(stdout);
  582.     (void) Delay(40L);
  583.  }
  584.  
  585.  
  586. disphelp()
  587.  {
  588.     clear();
  589.     (void) printf("\
  590. Commands: t or RETURN     : thumb the deck 3 cards at a time\n\
  591.           m [d1-7] [1-7a] : move cards or runs\n\
  592.           a               : turn on the auto pilot (in case you get stuck)\n\
  593.           s               : shuffle the deck (cheat!)\n\
  594.           p [2-7]         : put a hidden pile into the deck (cheat!)\n\
  595.           d               : print the cards in the deck (cheat!)\n\
  596.           w [2-7]         : print the cards in a hidden pile (cheat!)\n\
  597.           h or ?          : print this command summary\n\
  598.           r               : print the rules of the game\n\
  599.           q               : quit\n\n");
  600.     (void) printf("\
  601. Moving:   1-7, 'd', or 'a' select the source and destination for a move.\n\
  602.           Valid moves are from a run to a run, from the deck to a run,\n\
  603.           from a run to an ace pile, and from the deck to an ace pile.\n\n\
  604. Cheating: Commands that allow cheating are available but they will count\n\
  605.           against you in your next life!\n\n\nHit Return -");
  606.     (void) fflush(stdout);
  607.     (void) getchar();
  608.     redraw(TRUE);
  609.  }
  610.  
  611. disprules()
  612.  {
  613.     clear();
  614.     (void) printf("\
  615. Object:   The object of this game is to get all of the cards in each suit\n\
  616.           in order on the proper ace pile.\n\n\
  617. Rules:    Cards are played on the ace piles in ascending order: A,2,...,K. \n\
  618.           All aces are automatically placed in the correct aces pile as\n\
  619.           they're found in the deck or in a pile of hidden cards.  Once a\n\
  620.           card is placed in an ace pile it can't be removed.\n\n");
  621.     (void) printf("\
  622.           Cards must be played in descending order: K,Q,..,2, on the seven\n\
  623.           runs which are initially dealt.  They must always be played on a\n\
  624.           card of the opposite color.  Runs must always be moved as a\n\
  625.           whole, unless you're moving the lowest card on a run to the\n\
  626.           correct ace pile.\n\n");
  627.     (void) printf("\
  628.           Whenever a whole run is moved, the top hidden card is turned\n\
  629.           over, thus becoming the beginning of a new run.  If there are no\n\
  630.           hidden cards left, a space is created which can only be filled by\n\
  631.           a king.\n\n\
  632.           The rest of the deck is thumbed 3 cards at a time, until you spot a\n\
  633.           valid move.  Whenever the bottom of the deck is reached, the cards\n\
  634.           are turned over and you can continue thumbing.\n\n\nHit Return -");
  635.     (void) fflush(stdout);
  636.     (void) getchar();
  637.     redraw(TRUE);
  638.  }
  639.  
  640. getst(getbuf)
  641. char *getbuf;
  642.  {
  643.     int ch;
  644.     int nc;
  645.  
  646.     *(resgb = getbuf) = nc = 0;
  647.     for (;;)
  648.      {
  649.     if ((((ch = getchar()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
  650.      {
  651.         *getbuf++ = ch;
  652.         *getbuf = 0;
  653.         nc++;
  654.         (void) putchar(ch);
  655.         (void) fflush(stdout);
  656.      }
  657.     else if (ch == '\b')
  658.      {
  659.         if (nc--)
  660.          {
  661.             *--getbuf = 0;
  662.         (void) printf("\b \b");
  663.         (void) fflush(stdout);
  664.          }
  665.         else
  666.           return(FALSE);
  667.      }
  668.     else if (ch == ('r' & 0x1f))
  669.       redraw(TRUE);
  670.     else if (ch == '\r')
  671.       return(TRUE);
  672.      }
  673.  }
  674.  
  675. shuffle(cards)
  676. int *cards;
  677.  {
  678.     int i, j, k, t;
  679.  
  680.     for (i = 0; cards[i] != -1; i++)
  681.       ;
  682.     if (i)
  683.      {
  684.     for (j = 0; j < i; j++)
  685.      {
  686.         do
  687.           k = rnd(i);
  688.          while (k == j);
  689.         t = cards[j];
  690.         cards[j] = cards[k];
  691.         cards[k] = t;
  692.      }
  693.      }
  694.  }
  695.  
  696. rnd(n)
  697.  {
  698.     return(((rand() >> 12 | rand() >> 24) & (unsigned) ~0 >> 1) % n);
  699.  }
  700.  
  701. lstlen(list)
  702. int *list;
  703.  {
  704.     int i;
  705.  
  706.     for (i = 0; list[i] != -1; i++)
  707.       ;
  708.     return(i);
  709.  }
  710.  
  711.  
  712. xputc(c)
  713. register c;
  714.  {
  715.     (void) putchar(c);
  716.  }
  717.  
  718. init()
  719.  {
  720.  printf("\033\143");
  721.  printf("\233H\233J");
  722.  }
  723.  
  724. deinit()
  725.  {
  726.  }
  727.  
  728. clear()
  729.  {
  730.  printf("\233H\233J");
  731.  }
  732.  
  733. cleol()
  734.  {
  735.     printf("\233K");
  736.  }
  737.  
  738. standout()
  739.  {
  740.     putchar('\233');
  741.     printf("42m");
  742.  }
  743.  
  744. standend()
  745.  {
  746.     putchar('\233');
  747.     printf("40m");
  748.  }
  749.  
  750. moveto(y, x)
  751.  {
  752.     printf("\233%d;%dH",(y)+1,(x));
  753.  }
  754.  
  755. put(dest, item)
  756. int *dest;
  757.  {
  758.     if (item == -1)
  759.       return;
  760.     while (*dest != -1)
  761.       dest++;
  762.     *dest++ = item;
  763.     *dest = -1;
  764.  }
  765.  
  766. get(source)
  767. int *source;
  768.  {
  769.     int i;
  770.  
  771.     for (i = 0; *source != -1; i++, source++)
  772.       ;
  773.     if (i)
  774.      {
  775.     i = *--source;
  776.     *source = -1;
  777.     return(i);
  778.      }
  779.     return(-1);
  780.  }
  781.  
  782. peek(source)
  783. int *source;
  784.  {
  785.     int i;
  786.  
  787.     for (i = 0; source[i] != -1; i++)
  788.       ;
  789.     return(i ? source[i - 1] : -1);
  790.  }
  791.  
  792. _abort()
  793. {
  794. (void) getchar();
  795. unwind();
  796. }
  797.